package com.panfeng.xcloud.scheduler.util;

import com.panfeng.xcloud.common.core.candle.MyCandleEntry;
import org.apache.commons.math3.stat.regression.SimpleRegression;

import java.util.ArrayList;
import java.util.List;

public class TrendLines {

    public static class TrendLine {
        private List<Double> supportPrices;
        private List<Double> resistancePrices;
        private boolean isRecentCandlesWithinTrend;

        public TrendLine(List<Double> supportPrices, List<Double> resistancePrices, boolean isRecentCandlesWithinTrend) {
            this.supportPrices = supportPrices;
            this.resistancePrices = resistancePrices;
            this.isRecentCandlesWithinTrend = isRecentCandlesWithinTrend;
        }

        public List<Double> getSupportPrices() {
            return supportPrices;
        }

        public List<Double> getResistancePrices() {
            return resistancePrices;
        }

        public boolean isRecentCandlesWithinTrend() {
            return isRecentCandlesWithinTrend;
        }

        @Override
        public String toString() {
            return "Support Prices: " + supportPrices + "\nResistance Prices: " + resistancePrices +
                    "\nRecent Candles Within Trend: " + isRecentCandlesWithinTrend;
        }
    }

    public static TrendLine calculateSupportAndResistanceLines(List<MyCandleEntry> candles) {
        int mid = candles.size() / 2;
        List<MyCandleEntry> firstHalf = candles.subList(0, mid);
        List<MyCandleEntry> secondHalf = candles.subList(mid, candles.size());

        double[] firstMax = findMax(firstHalf);
        double[] secondMax = findMax(secondHalf);

        double[] firstMin = findMin(firstHalf);
        double[] secondMin = findMin(secondHalf);

        SimpleRegression resistanceRegression = new SimpleRegression();
        resistanceRegression.addData(firstMax[0] + 0, firstMax[1]);
        resistanceRegression.addData(secondMax[0] + mid, secondMax[1]);

        SimpleRegression supportRegression = new SimpleRegression();
        supportRegression.addData(firstMin[0] + 0, firstMin[1]);
        supportRegression.addData(secondMin[0] + mid, secondMin[1]);

        List<Double> supportPrices = new ArrayList<>();
        List<Double> resistancePrices = new ArrayList<>();

        // 检查最近的几根蜡烛的开盘价和收盘价是否在支撑线和阻力线之间
        boolean isRecentCandlesWithinTrend = true;
        for (int i = 0; i < candles.size(); i++) {
            MyCandleEntry myCandleEntry = candles.get(i);
            double supportPrice = supportRegression.predict(i);
            double resistancePrice = resistanceRegression.predict(i);
            supportPrices.add(supportPrice);
            resistancePrices.add(resistancePrice);

            if (isRecentCandlesWithinTrend) {
                if (myCandleEntry.getOpen() < supportPrice || myCandleEntry.getOpen() > resistancePrice ||
                        myCandleEntry.getClose() < supportPrice || myCandleEntry.getClose() > resistancePrice) {
                    isRecentCandlesWithinTrend = false;
                }
            }
        }

        return new TrendLine(supportPrices, resistancePrices, isRecentCandlesWithinTrend);
    }

    private static double[] findMax(List<MyCandleEntry> candles) {
        double max = Double.MIN_VALUE;
        int index = -1;
        for (int i = 0; i < candles.size(); i++) {
            if (candles.get(i).getHigh() > max) {
                max = candles.get(i).getHigh();
                index = i;
            }
        }
        return new double[]{index, max};
    }

    private static double[] findMin(List<MyCandleEntry> candles) {
        double min = Double.MAX_VALUE;
        int index = -1;
        for (int i = 0; i < candles.size(); i++) {
            if (candles.get(i).getLow() < min) {
                min = candles.get(i).getLow();
                index = i;
            }
        }
        return new double[]{index, min};
    }

}
